from editor_base import EditorBase

from ..bases import widgets


class CueStackEditor(EditorBase):
    topwidget_label = 'Cue Stacks'
    _Properties = {'cue_index':dict(default=0, min=0, max=9999), 
                   'next_index':dict(default=0, min=0, max=9999)}
    def init_editor(self, **kwargs):
        self.current_cue_members = set()
        self.stack = kwargs.get('stack')
        
        frame = widgets.Frame(label='Cue Stack Properties')
        self.txtStackName = widgets.Entry(name='Name', Property=(self.stack, 'name'))
        frame.pack_start(self.txtStackName.topwidget)
        self.sbStackIndex = widgets.SpinBtn(label='Stack Index', Property=(self.stack, 'Index'))
        frame.pack_start(self.sbStackIndex.topwidget)
        btn = widgets.Button(label='Add a Playback for this Stack')
        btn.connect('clicked', self.on_btnAddPlayback_clicked)
        frame.pack_start(btn)   
        self.playback_fader = None
   
        self.topwidget.pack_start(frame)
        
        i = self.stack.current_index
        if not i:
            i = 1
        self.cue_index = i
        self.next_index = i
        hbox = widgets.HBox()
        
        list_types = [str, int, str, float]
        col_names = ['id', 'Index', 'Name', 'Fade Time']
        col_order = [1, 2, 3]
        columns_editable = [1, 2, 3]
        self.column_attr_map = {0:'id', 1:'Index', 2:'name', 3:'fade_time'}
        self.list = widgets.TreeList(name='Cues', list_types=list_types, default_sort_column=1, 
                                     column_names=col_names, column_order=col_order, 
                                     columns_editable=columns_editable)
        self.update_list()
        self.list.connect('cell_edited', self.on_cell_edited)
        self.list.connect('selection_changed', self.on_list_selection_changed)
        
        if self.stack.playback:
            self.add_playback_controls()
        
        self.spCueIndex = widgets.SpinBtn(label='Current', Property=(self, 'cue_index'), no_frame=True)
        self.spNextIndex = widgets.SpinBtn(label='Next', Property=(self, 'next_index'), no_frame=True)
        self.btn_record = widgets.Button(label='Record Cue')
        self.btn_record.connect('clicked', self.on_btn_record_clicked)
        self.btn_recall = widgets.Button(label='Recall')
        self.btn_recall.connect('clicked', self.on_btn_recall_clicked)
        
        hbox2 = widgets.HBox()
        hbox2.pack_start(self.spCueIndex.topwidget)
        hbox2.pack_start(self.spNextIndex.topwidget)
        
        hbox3 = widgets.HBox()
        hbox3.pack_start(self.btn_record)
        hbox3.pack_start(self.btn_recall)
        
        self.list.topwidget.pack_start(hbox2)
        self.list.topwidget.pack_start(hbox3)
        
        hbox.pack_start(self.list.topwidget, expand=True)
        
        self.topwidget.pack_start(hbox, expand=True)
        
        
        self.group_list = widgets.TreeList(name='Group Selection', 
                                           column_names=['id', 'Name', 'Selected', 'active'], 
                                           list_types=[str, str, bool, bool], 
                                           column_order=[1, 2], 
                                           columns_editable=[2])
        self.update_group_list()
        self.group_list.connect('cell_toggled', self.on_group_list_cell_toggled)
        self.topwidget.pack_start(self.group_list.topwidget, expand=True)
        
        self.stack.connect('new_snapshot', self.on_new_snapshot)
        self.stack.connect('current_index_changed', self.on_stack_current_index_changed)
        self.MainController.connect('new_group', self.on_mc_new_group)
        
    def unlink(self):
        super(CueStackEditor, self).unlink()
        self.stack.disconnect(callback=self.on_new_snapshot)
        self.MainController.disconnect(callback=self.on_mc_new_group)
        self.txtStackName.unlink()
        self.sbStackIndex.unlink()
        if self.playback_fader:
            self.playback_fader.unlink()
            w = self.playback_fader.topwidget
            w.get_parent().remove(w)
        
#    @property
#    def current_cue_members(self):
#        key = self.list.current_selection
#        if key is None:
#            return []
#        snapshot = self.stack.Snapshots[key]
#        return snapshot.root_members
    
    def update_list(self, key=None):
        if key is not None:
            snapshots = {key:self.stack.Snapshots[key]}
        else:
            snapshots = self.stack.Snapshots
        for key, val in snapshots.iteritems():
            values = [getattr(val, self.column_attr_map[x]) for x in [1, 2, 3]]
            self.list.update({key:values})
                
    def update_group_list(self, key=None):
        if key is not None:
            groups = {key:self.MainController.Groups[key]}
        else:
            groups = self.MainController.Groups
        for key, val in groups.iteritems():
            self.group_list.update({key:[val.name, key in self.current_cue_members, True]})
    
    def on_new_snapshot(self, **kwargs):
        key = kwargs.get('id')
        self.update_list(key)
        
    def on_stack_current_index_changed(self, **kwargs):
        current = kwargs.get('value')
        next = kwargs.get('next')
        self.cue_index = current
        self.next_index = next
        #self.spCueIndex.on_object_value_changed()
        #self.spNextIndex.on_object_value_changed()
    
    def add_playback_controls(self):
        pb = self.stack.playback
        self.playback_fader = widgets.VSlider(Property=(pb, 'value'))
        w = self.list.topwidget.get_parent()
        w.pack_start(self.playback_fader.topwidget, expand=True)
        self.playback_fader.topwidget.show_all()
        
    def on_btnAddPlayback_clicked(self, btn):
        self.MainController.add_playback(stack=self.stack)
        self.add_playback_controls()
    
    def on_btn_record_clicked(self, btn):
        # TODO: change the source to selected after MainController selection implemented
        groups = [self.MainController.Groups[key] for key in self.current_cue_members]
        self.MainController.store_to_CueStack(stack=self.stack, index=int(self.cue_index), source=groups)
        #print self.MainController.Selection.members.values()
        
    def on_btn_recall_clicked(self, btn):
        if self.cue_index in self.stack.Snapshots.indexed_items:
            self.stack.recall_snapshot(index=self.next_index)
    
    def on_cell_edited(self, **kwargs):
        key = kwargs.get('key')
        column = kwargs.get('column')
        value = kwargs.get('value')
        attr = self.column_attr_map[column]
        setattr(self.stack.Snapshots[key], attr, value)
        self.update_list()
    
    def on_list_selection_changed(self, **kwargs):
        key = kwargs.get('key')
        snapshot = self.stack.Snapshots[key]
        self.cue_index = snapshot.Index
        self.next_index = snapshot.Index
        #self.spCueIndex.on_object_value_changed()
        #self.spNextIndex.on_object_value_changed()
        self.update_group_list()
        if snapshot.members:
            #self.current_cue_members.clear()
            self.current_cue_members |= snapshot.root_members
            self.update_group_list()
        
    def on_group_list_cell_toggled(self, **kwargs):
        grkey = kwargs.get('key')
        if kwargs.get('state'):
            self.current_cue_members.add(grkey)
        else:
            self.current_cue_members.discard(grkey)
        self.update_group_list(grkey)
        
    def on_mc_new_group(self, **kwargs):
        key = kwargs.get('id')
        self.update_group_list(key)
        
